home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / mozilla-firefox / include / layout / nsTextTransformer.h < prev    next >
C/C++ Source or Header  |  2006-05-08  |  15KB  |  393 lines

  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/MPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is Mozilla Communicator client code.
  16.  *
  17.  * The Initial Developer of the Original Code is
  18.  * Netscape Communications Corporation.
  19.  * Portions created by the Initial Developer are Copyright (C) 1998
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *
  24.  * Alternatively, the contents of this file may be used under the terms of
  25.  * either of the GNU General Public License Version 2 or later (the "GPL"),
  26.  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27.  * in which case the provisions of the GPL or the LGPL are applicable instead
  28.  * of those above. If you wish to allow use of your version of this file only
  29.  * under the terms of either the GPL or the LGPL, and not to allow others to
  30.  * use your version of this file under the terms of the MPL, indicate your
  31.  * decision by deleting the provisions above and replace them with the notice
  32.  * and other provisions required by the GPL or the LGPL. If you do not delete
  33.  * the provisions above, a recipient may use your version of this file under
  34.  * the terms of any one of the MPL, the GPL or the LGPL.
  35.  *
  36.  * ***** END LICENSE BLOCK ***** */
  37. #ifndef nsTextTransformer_h___
  38. #define nsTextTransformer_h___
  39.  
  40. #include "nsTextFragment.h"
  41. #include "nsISupports.h"
  42. #include "nsPresContext.h"
  43. #include "nsIObserver.h"
  44. #ifdef IBMBIDI
  45. #include "nsBidi.h"
  46. #include "nsBidiUtils.h"
  47. #endif
  48.  
  49. class nsIContent;
  50. class nsIFrame;
  51. class nsILineBreaker;
  52. class nsIWordBreaker;
  53.  
  54. // XXX I'm sure there are other special characters
  55. #define CH_NBSP 160
  56. #define CH_ENSP 8194        //<!ENTITY ensp    CDATA " " -- en space, U+2002 ISOpub -->
  57. #define CH_EMSP 8195        //<!ENTITY emsp    CDATA " " -- em space, U+2003 ISOpub -->
  58. #define CH_THINSP 8291    //<!ENTITY thinsp  CDATA " " -- thin space, U+2009 ISOpub -->
  59. #define CH_ZWNJ    8204    //<!ENTITY zwnj    CDATA "‌" -- zero width non-joiner, U+200C NEW RFC 2070
  60. #define CH_SHY  173
  61.  
  62. #ifdef IBMBIDI
  63. #define CH_ZWJ  8205  //<!ENTITY zwj     CDATA "‍" -- zero width joiner, U+200D NEW RFC 2070 -->
  64. #define CH_LRM  8206  //<!ENTITY lrm     CDATA "‎" -- left-to-right mark, U+200E NEW RFC 2070 -->
  65. #define CH_RLM  8207  //<!ENTITY rlm     CDATA "‏" -- right-to-left mark, U+200F NEW RFC 2070 -->
  66. #define CH_LRE  8234  //<!CDATA "‪" -- left-to-right embedding, U+202A -->
  67. #define CH_RLE  8235  //<!CDATA "‫" -- right-to-left embedding, U+202B -->
  68. #define CH_PDF  8236  //<!CDATA "‬" -- pop directional format, U+202C -->
  69. #define CH_LRO  8237  //<!CDATA "‭" -- left-to-right override, U+202D -->
  70. #define CH_RLO  8238  //<!CDATA "‮" -- right-to-left override, U+202E -->
  71.  
  72. #define IS_BIDI_CONTROL(_ch) \
  73.   (((_ch) >= CH_LRM && (_ch) <= CH_RLM) \
  74.   || ((_ch) >= CH_LRE && (_ch) <= CH_RLO))
  75. #endif // IBMBIDI
  76.  
  77. // For now, we have only a couple of characters to strip out. If we get
  78. // any more, change this to use a bitset to lookup into.
  79. //   CH_SHY - soft hyphen (discretionary hyphen)
  80. #ifdef IBMBIDI
  81. // added BIDI formatting codes
  82. #define IS_DISCARDED(_ch) \
  83.   (((_ch) == CH_SHY) || ((_ch) == '\r') || IS_BIDI_CONTROL(_ch))
  84. #else
  85. #define IS_DISCARDED(_ch) \
  86.   (((_ch) == CH_SHY) || ((_ch) == '\r'))
  87. #endif
  88.  
  89. #define IS_ASCII_CHAR(ch) ((ch&0xff80) == 0)
  90.  
  91. #define NS_TEXT_TRANSFORMER_AUTO_WORD_BUF_SIZE 128 // used to be 256
  92.  
  93. // Indicates whether the transformed text should be left as ascii
  94. #define NS_TEXT_TRANSFORMER_LEAVE_AS_ASCII                    1
  95.  
  96. // If at any point during GetNextWord or GetPrevWord we
  97. // run across a multibyte (> 127) unicode character.
  98. #define NS_TEXT_TRANSFORMER_HAS_MULTIBYTE                    2
  99.  
  100. // The text in the transform buffer is ascii
  101. #define NS_TEXT_TRANSFORMER_TRANSFORMED_TEXT_IS_ASCII        4
  102.  
  103. #ifdef IBMBIDI
  104. // The text in the transform buffer needs Arabic shaping
  105. #define NS_TEXT_TRANSFORMER_DO_ARABIC_SHAPING 8
  106.  
  107. // The text in the transform buffer needs numeric shaping
  108. #define NS_TEXT_TRANSFORMER_DO_NUMERIC_SHAPING 16
  109. #endif
  110.  
  111. // A growable text buffer that tries to avoid using malloc by having a
  112. // builtin buffer. Ideally used as an automatic variable.
  113. class nsAutoTextBuffer {
  114. public:
  115.   nsAutoTextBuffer();
  116.   ~nsAutoTextBuffer();
  117.  
  118.   nsresult GrowBy(PRInt32 aAtLeast, PRBool aCopyToHead = PR_TRUE);
  119.  
  120.   nsresult GrowTo(PRInt32 aNewSize, PRBool aCopyToHead = PR_TRUE);
  121.  
  122.   PRUnichar* GetBuffer() { return mBuffer; }
  123.   PRUnichar* GetBufferEnd() { return mBuffer + mBufferLen; }
  124.   PRInt32 GetBufferLength() const { return mBufferLen; }
  125.  
  126.   PRUnichar* mBuffer;
  127.   PRInt32 mBufferLen;
  128.   PRUnichar mAutoBuffer[NS_TEXT_TRANSFORMER_AUTO_WORD_BUF_SIZE];
  129. };
  130.  
  131. //----------------------------------------
  132.  
  133. /**
  134.  * This object manages the transformation of text:
  135.  *
  136.  * <UL>
  137.  * <LI>whitespace compression
  138.  * <LI>capitalization
  139.  * <LI>lowercasing
  140.  * <LI>uppercasing
  141.  * <LI>ascii to Unicode (if requested)
  142.  * <LI>discarded characters
  143.  * <LI>conversion of   that is not part of whitespace into a space
  144.  * <LI>tab and newline characters to space (normal text only)
  145.  * </UL>
  146.  *
  147.  * Note that no transformations are applied that would impact word
  148.  * breaking (like mapping   into space, for example). In
  149.  * addition, this logic will not strip leading or trailing whitespace
  150.  * (across the entire run of text; leading whitespace can be skipped
  151.  * for a frames text because of whitespace compression).
  152.  */
  153. class nsTextTransformer {
  154. public:
  155.   // Note: The text transformer does not hold a reference to the line
  156.   // breaker and work breaker objects
  157.   nsTextTransformer(nsILineBreaker* aLineBreaker,
  158.                     nsIWordBreaker* aWordBreaker,
  159.                     nsPresContext* aPresContext);
  160.  
  161.   ~nsTextTransformer();
  162.  
  163.   /**
  164.    * Initialize the text transform. Use GetNextWord() and GetPrevWord()
  165.    * to iterate the text
  166.    *
  167.    * The default is to transform all text to Unicode; however, you can
  168.    * specify that the text should be left as ascii if possible. Note that
  169.    * we don't step the text down from Unicode to ascii (even if it doesn't
  170.    * contain multibyte characters) so this only happens for text fragments
  171.    * that contain 1-byte text.
  172.    * XXX This is currently not implemented for GetPreviousWord()
  173.    * @see TransformedTextIsAscii()
  174.    */
  175.   nsresult Init(nsIFrame* aFrame,
  176.                 nsIContent* aContent,
  177.                 PRInt32 aStartingOffset,
  178.                 PRBool aForceArabicShaping = PR_FALSE,
  179.                 PRBool aLeaveAsAscii = PR_FALSE);
  180.  
  181.   PRInt32 GetContentLength() const {
  182.     return mFrag ? mFrag->GetLength() : 0;
  183.   }
  184.  
  185.   PRUnichar GetContentCharAt(PRInt32 aIndex) {
  186.     return (mFrag && aIndex < mFrag->GetLength()) ? mFrag->CharAt(aIndex) : 0;
  187.   }
  188.  
  189.   /**
  190.    * Iterates the next word in the text fragment.
  191.    *
  192.    * Returns a pointer to the word, the number of characters in the word, the
  193.    * content length of the word, whether it is whitespace, and whether the
  194.    * text was transformed (any of the transformations listed above). The content
  195.    * length can be greater than the word length if whitespace compression occured
  196.    * or if characters were discarded
  197.    *
  198.    * The default behavior is to reset the transform buffer to the beginning,
  199.    * but you can choose to not reste it and buffer across multiple words
  200.    */
  201.   PRUnichar* GetNextWord(PRBool aInWord,
  202.                          PRInt32* aWordLenResult,
  203.                          PRInt32* aContentLenResult,
  204.                          PRBool* aIsWhitespaceResult,
  205.                          PRBool* aWasTransformed,
  206.                          PRBool aResetTransformBuf = PR_TRUE,
  207.                          PRBool aForLineBreak = PR_TRUE,
  208.                          PRBool aIsKeyboardSelect = PR_FALSE);
  209.  
  210.   PRUnichar* GetPrevWord(PRBool aInWord,
  211.                          PRInt32* aWordLenResult,
  212.                          PRInt32* aContentLenResult,
  213.                          PRBool* aIsWhitespaceResult,
  214.                          PRBool aForLineBreak = PR_TRUE,
  215.                          PRBool aIsKeyboardSelect = PR_FALSE);
  216.  
  217.   
  218.   // Returns PR_TRUE if the LEAVE_AS_ASCII flag is set
  219.   PRBool LeaveAsAscii() const {
  220.       return (mFlags & NS_TEXT_TRANSFORMER_LEAVE_AS_ASCII) != 0;
  221.   }
  222.  
  223.   // Returns PR_TRUE if any of the characters are multibyte (greater than 127)
  224.   PRBool HasMultibyte() const {
  225.       return (mFlags & NS_TEXT_TRANSFORMER_HAS_MULTIBYTE) != 0;
  226.   }
  227.  
  228.   // Returns PR_TRUE if the text in the transform bufer is ascii (i.e., it
  229.   // doesn't contain any multibyte characters)
  230.   PRBool TransformedTextIsAscii() const {
  231.       return (mFlags & NS_TEXT_TRANSFORMER_TRANSFORMED_TEXT_IS_ASCII) != 0;
  232.   }
  233.  
  234. #ifdef IBMBIDI
  235.   // Returns PR_TRUE if the text in the transform bufer needs Arabic
  236.   // shaping
  237.   PRBool NeedsArabicShaping() const {
  238.     return (mFlags & NS_TEXT_TRANSFORMER_DO_ARABIC_SHAPING) != 0;
  239.   }
  240.   
  241.   // Returns PR_TRUE if the text in the transform bufer needs numeric
  242.   // shaping
  243.   PRBool NeedsNumericShaping() const {
  244.     return (mFlags & NS_TEXT_TRANSFORMER_DO_NUMERIC_SHAPING) != 0;
  245.   }
  246. #endif
  247.  
  248.   // Set or clears the LEAVE_AS_ASCII bit
  249.   void SetLeaveAsAscii(PRBool aValue) {
  250.       aValue ? mFlags |= NS_TEXT_TRANSFORMER_LEAVE_AS_ASCII : 
  251.                mFlags &= (~NS_TEXT_TRANSFORMER_LEAVE_AS_ASCII);
  252.   }
  253.       
  254.   // Set or clears the NS_TEXT_TRANSFORMER_HAS_MULTIBYTE bit
  255.   void SetHasMultibyte(PRBool aValue) {
  256.       aValue ? mFlags |= NS_TEXT_TRANSFORMER_HAS_MULTIBYTE : 
  257.                mFlags &= (~NS_TEXT_TRANSFORMER_HAS_MULTIBYTE);
  258.   }
  259.  
  260.   // Set or clears the NS_TEXT_TRANSFORMER_TRANSFORMED_TEXT_IS_ASCII bit
  261.   void SetTransformedTextIsAscii(PRBool aValue) {
  262.       aValue ? mFlags |= NS_TEXT_TRANSFORMER_TRANSFORMED_TEXT_IS_ASCII : 
  263.                mFlags &= (~NS_TEXT_TRANSFORMER_TRANSFORMED_TEXT_IS_ASCII);
  264.   }
  265.  
  266. #ifdef IBMBIDI
  267.   // Set or clears the NS_TEXT_TRANSFORMER_TRANSFORMED_DO_ARABIC_SHAPING bit
  268.   void SetNeedsArabicShaping(PRBool aValue) {
  269.     aValue ? mFlags |= NS_TEXT_TRANSFORMER_DO_ARABIC_SHAPING : 
  270.              mFlags &= (~NS_TEXT_TRANSFORMER_DO_ARABIC_SHAPING);
  271.   }
  272.  
  273.   // Set or clears the NS_TEXT_TRANSFORMER_TRANSFORMED_DO_NUMERIC_SHAPING bit
  274.   void SetNeedsNumericShaping(PRBool aValue) {
  275.     aValue ? mFlags |= NS_TEXT_TRANSFORMER_DO_NUMERIC_SHAPING : 
  276.                        mFlags &= (~NS_TEXT_TRANSFORMER_DO_NUMERIC_SHAPING);
  277.   }
  278. #endif
  279.   
  280.   PRUnichar* GetWordBuffer() {
  281.     return mTransformBuf.GetBuffer();
  282.   }
  283.  
  284.   PRInt32 GetWordBufferLength() const {
  285.     return mTransformBuf.GetBufferLength();
  286.   }
  287.  
  288.   static PRBool GetWordSelectEatSpaceAfter() {
  289.       return sWordSelectEatSpaceAfter;
  290.   }
  291.   
  292.   static PRBool GetWordSelectStopAtPunctuation() {
  293.       return sWordSelectStopAtPunctuation;
  294.   }
  295.   
  296.   static nsresult Initialize();
  297.   static void Shutdown();
  298.  
  299. protected:
  300.   // Helper methods for GetNextWord (F == forwards)
  301.   PRInt32 ScanNormalWhiteSpace_F();
  302.   PRInt32 ScanNormalAsciiText_F(PRInt32* aWordLen,
  303.                                 PRBool*  aWasTransformed);
  304.   PRInt32 ScanNormalAsciiText_F_ForWordBreak(PRInt32* aWordLen,
  305.                                 PRBool*  aWasTransformed,
  306.                                 PRBool aIsKeyboardSelect);
  307.   PRInt32 ScanNormalUnicodeText_F(PRBool aForLineBreak,
  308.                                   PRInt32* aWordLen,
  309.                                   PRBool*  aWasTransformed);
  310.   PRInt32 ScanPreWrapWhiteSpace_F(PRInt32* aWordLen);
  311.   PRInt32 ScanPreAsciiData_F(PRInt32* aWordLen,
  312.                              PRBool*  aWasTransformed);
  313.   PRInt32 ScanPreData_F(PRInt32* aWordLen,
  314.                         PRBool*  aWasTransformed);
  315.  
  316.   // Helper methods for GetPrevWord (B == backwards)
  317.   PRInt32 ScanNormalWhiteSpace_B();
  318.   PRInt32 ScanNormalAsciiText_B(PRInt32* aWordLen, PRBool aIsKeyboardSelect);
  319.   PRInt32 ScanNormalUnicodeText_B(PRBool aForLineBreak, PRInt32* aWordLen);
  320.   PRInt32 ScanPreWrapWhiteSpace_B(PRInt32* aWordLen);
  321.   PRInt32 ScanPreData_B(PRInt32* aWordLen);
  322.  
  323.   // Converts the current text in the transform buffer from ascii to
  324.   // Unicode
  325.   void ConvertTransformedTextToUnicode();
  326.   
  327.   void LanguageSpecificTransform(PRUnichar* aText, PRInt32 aLen,
  328.                                  PRBool* aWasTransformed);
  329.  
  330.   void DoArabicShaping(PRUnichar* aText, PRInt32& aTextLength, PRBool* aWasTransformed);
  331.  
  332.   void DoNumericShaping(PRUnichar* aText, PRInt32& aTextLength, PRBool* aWasTransformed);
  333.  
  334.   void StripZeroWidthJoinControls(PRUnichar* aSource, PRUnichar* aTarget, PRInt32& aTextLength, PRBool* aWasTransformed);
  335.  
  336.   // The text fragment that we are looking at
  337.   const nsTextFragment* mFrag;
  338.  
  339.   // Our current offset into the text fragment
  340.   PRInt32 mOffset;
  341.  
  342.   // The frame's white-space mode we are using to process text
  343.   enum {
  344.     eNormal,
  345.     ePreformatted,
  346.     ePreWrap
  347.   } mMode;
  348.   
  349.   nsILineBreaker* mLineBreaker;  // [WEAK]
  350.  
  351.   nsIWordBreaker* mWordBreaker;  // [WEAK]
  352.  
  353.   nsLanguageSpecificTransformType mLanguageSpecificTransformType;
  354.  
  355. #ifdef IBMBIDI
  356.   nsPresContext* mPresContext;
  357.   nsCharType      mCharType;
  358. #endif
  359.  
  360.   // Buffer used to hold the transformed words from GetNextWord or
  361.   // GetPrevWord
  362.   nsAutoTextBuffer mTransformBuf;
  363.  
  364.   // Our current position within the buffer. Used when iterating the next
  365.   // word, because we may be requested to buffer across multiple words
  366.   PRInt32 mBufferPos;
  367.   
  368.   // The frame's text-transform state
  369.   PRUint8 mTextTransform;
  370.  
  371.   // Flag for controling mLeaveAsAscii, mHasMultibyte, mTransformedTextIsAscii
  372.   PRUint8 mFlags;
  373.  
  374.   // prefs used to configure the double-click word selection behavior
  375.   static int WordSelectPrefCallback(const char* aPref, void* aClosure);
  376.   static PRBool sWordSelectListenerPrefChecked;  // have we read the prefs yet?
  377.   static PRBool sWordSelectEatSpaceAfter;        // should we include whitespace up to next word? 
  378.   static PRBool sWordSelectStopAtPunctuation;    // should we stop at punctuation?
  379.  
  380. #ifdef DEBUG
  381.   static void SelfTest(nsILineBreaker* aLineBreaker,
  382.                        nsIWordBreaker* aWordBreaker,
  383.                        nsPresContext* aPresContext);
  384.  
  385.   nsresult Init2(const nsTextFragment* aFrag,
  386.                  PRInt32 aStartingOffset,
  387.                  PRUint8 aWhiteSpace,
  388.                  PRUint8 aTextTransform);
  389. #endif
  390. };
  391.  
  392. #endif /* nsTextTransformer_h___ */
  393.